package org.adorsys.aderp.aderplogin.roles;

import java.util.Collection;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

/**
 * This voter works on contextual roles. 
 * 
 * A contextual role hat 2 parts. The permission profile starting with
 * PP_ and the context.
 * 
 * @author francis
 *
 */
public class ContextualRoleVoter extends RoleVoter {

	private ContextualAttrEvalFactory contextualAttrEvalFactory;
	
	@Override
	public String getRolePrefix() {
		return "PP_";
	}

	@Override
	public int vote(Authentication authentication, Object object,
			Collection<ConfigAttribute> attributes) {
        int result = ACCESS_ABSTAIN;
        Collection<? extends GrantedAuthority> authorities = readAuthorities(authentication);

        for (ConfigAttribute attribute : attributes) {
            if (this.supports(attribute)) {
                result = ACCESS_DENIED;
                ContextualAttrEval evaluator = contextualAttrEvalFactory.newEvaluator(attribute.getAttribute());

                // Attempt to find a matching granted authority
                for (GrantedAuthority authority : authorities) {
                	if(ACCESS_GRANTED==evaluator.match(authority.getAuthority())) return  ACCESS_GRANTED;
                }
            }
        }

        return result;
	}

    Collection<? extends GrantedAuthority> readAuthorities(Authentication authentication) {
        return authentication.getAuthorities();
    }

	public ContextualAttrEvalFactory getContextualAttrEvalFactory() {
		return contextualAttrEvalFactory;
	}

	public void setContextualAttrEvalFactory(
			ContextualAttrEvalFactory contextualAttrEvalFactory) {
		this.contextualAttrEvalFactory = contextualAttrEvalFactory;
	}
}
